# BSD3.0
# cili@163.com

import random
import tkinter as tk
from tkinter import ttk

class BubbleSortVisualization:
    def __init__(self, root):
        self.root = root
        self.time_space = 500

        self.canvas_panel = ttk.Frame(self.root)
        self.canvas_panel.pack(side="top", fill="both", expand=True)
        self.button_panel = ttk.Frame(self.root)
        self.button_panel.pack(side="top", fill="both", expand=True)

        self.cavas_width, self.cavas_height = 500, 280
        self.canvas = tk.Canvas(self.canvas_panel, width=self.cavas_width, height=self.cavas_height)
        self.canvas.grid(row=0, column=0, padx=5)

        self.text_area = tk.Text(self.canvas_panel, width=60, height=16)
        self.text_area.grid(row=0, column=1, columnspan=2, padx=5)

        self.initialize_button = ttk.Button(self.button_panel, text="数据初始化", command=self.initialize_data)
        self.initialize_button.pack(side="left", padx=5, pady=5, fill="both", expand=True)

        self.next_round_button = ttk.Button(self.button_panel, text="下一轮", command=self.next_round)
        self.next_round_button.pack(side="left", padx=5, pady=5, fill="both", expand=True)

        self.auto_sort_button = ttk.Button(self.button_panel, text="自动排序", command=self.auto_sort)
        self.auto_sort_button.pack(side="left", padx=5, pady=5, fill="both", expand=True)

        self.initialize_data()
        self.update_chart_id = self.root.after(0, self.update_chart, [])



    def bubble_sort(self, nums):
        n = len(self.data)
        for i in range(nums):
            for j in range(0, n - self.current_round - 1):
                if self.data[j] > self.data[j + 1]:
                    self.data[j], self.data[j + 1] = self.data[j + 1], self.data[j]
                    self.update_chart([j,j+1])
                    self.root.update()
                    self.root.after(self.time_space)
                    self.root.after_cancel(self.update_chart_id)
                    self.update_chart_id = self.root.after(self.time_space, self.update_chart, [])
            self.current_round = self.current_round + 1
        return self.current_round >= n

    def update_chart(self,positions):
        self.canvas.delete("all")
        bar_width = 20
        x = 10
        for i, value in enumerate(self.data):
            color = 'red' if i in positions else 'blue'
            self.canvas.create_rectangle(x, self.cavas_height - 50 - value, x + bar_width, self.cavas_height - 50, fill=color)
            self.canvas.create_text(x + bar_width / 2, self.cavas_height - 40, text=str(i + 1))
            self.canvas.create_text(x + bar_width / 2, self.cavas_height - 50 - value - 10, text=str(value))
            x = x + 30 + bar_width

    def initialize_data(self):
        self.data = [random.randint(1, 200) for _ in range(10)]
        self.text_area.delete(1.0, tk.END)
        self.update_chart_id = self.root.after(0, self.update_chart, (self.data, -1))
        self.text_area.insert(tk.END, f"第0轮：{self.data}\n")
        self.current_round = 0
        self.next_round_button.config(state="normal")
        self.auto_sort_button.config(state="normal")

    def next_round(self):
        self.next_round_button.config(state="disabled")
        self.auto_sort_button.config(state="disabled")
        flag = self.bubble_sort(1)
        self.text_area.insert(tk.END, f"第{self.current_round}轮：{self.data}\n")
        if not flag:
            self.next_round_button.config(state="normal")
            self.auto_sort_button.config(state="normal")
        else:
            self.text_area.insert(tk.END, f"排序结束\n")

    def auto_sort(self):
        self.initialize_button.config(state="disabled")
        self.next_round_button.config(state="disabled")
        self.auto_sort_button.config(state="disabled")
        for _ in range(len(self.data) - self.current_round):
            flag = self.bubble_sort(1)
            self.text_area.insert(tk.END, f"第{self.current_round}轮：{self.data}\n")
            if flag:
                self.initialize_button.config(state="normal")
                self.text_area.insert(tk.END, f"排序结束\n")

root = tk.Tk()
root.title("冒泡排序过程展示")
BubbleSortVisualization(root)
root.mainloop()